<?php

namespace App\Lib;

use App\Exceptions\InternalException;

/**
 * 助手函数.
 */
class Helper
{
    /**
     * 获取后台路由地址
     *
     * @param string $name
     *
     * @return string
     */
    public function getAdminRoute($name)
    {
        return route(config('admin.route.prefix').'.'.$name);
    }

    /**
     * 更新 env 环境变量文件.
     */
    public function updateEnv(array $data)
    {
        $envPath      = base_path().\DIRECTORY_SEPARATOR.'.env';
        $contentArray = collect(file($envPath, FILE_IGNORE_NEW_LINES));
        $contentArray->transform(function ($item) use ($data) {
            foreach ($data as $key => $value) {
                if (str_contains($item, $key)) {
                    return $key.'='.$value;
                }
            }

            return $item;
        });

        $content = implode("\n", $contentArray->toArray());
        \File::put($envPath, $content);
    }


    /**
     * @param string $url 网址
     * @param null $data    传递数据
     * @param int  $header  头信息
     * @param int  $timeout 超时设定
     *
     * @return mixed|string
     */
    public function curlInfo($url, $postFields = null, $header = null)
    {

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, 0);//设置是否返回response header
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 0);
//        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);

        //当需要通过curl_getinfo来获取发出请求的header信息时，该选项需要设置为true
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        //https 请求
        if (strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        //header
        if ($header) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }

        if (is_array($postFields) && 0 < count($postFields)) {
            $postBodyString = "";
            $postMultipart  = false;
            foreach ($postFields as $k => $v) {
                if ("@" != substr($v, 0, 1))//判断是不是文件上传
                {
                    $postBodyString .= "$k=" . urlencode($v) . "&";
                } else//文件上传用multipart/form-data，否则用www-form-urlencoded
                {
                    $postMultipart = true;
                }
            }
            unset($k, $v);
            curl_setopt($ch, CURLOPT_POST, true);
            if ($postMultipart) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1));
            }
        } elseif (!empty($postFields)) {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
        }
        $reponse = curl_exec($ch);
        //打印请求的header信息
        $request_header = curl_getinfo( $ch, CURLINFO_HEADER_OUT);
//        Log::info($request_header);

        if (curl_errno($ch)) {
            throw new InternalException(curl_error($ch), 0);
        } else {
            $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if (200 !== $httpStatusCode) {
                throw new InternalException($reponse, $httpStatusCode);
            }
        }
        curl_close($ch);
        return $reponse;
    }

    /**
     * 递归调用构建地址层级结构的函数
     * @param array|object $addresses
     * @param int $parentId
     * @return array
     * Date:    2024/5/4 10:54
     */
    public function buildAddressHierarchy($addresses, int $parentId = 0): array
    {
        $hierarchy = [];

        foreach ($addresses as $address) {
            if ($address['pid'] == $parentId) {
                // 递归构建子地址的层级结构
                $children = $this->buildAddressHierarchy($addresses, $address['code']);

                // 如果子地址存在，则将其添加到当前地址的children数组中
                if (!empty($children)) {
                    $address['children'] = $children;
                }

                // 将当前地址添加到层级结构中
                $hierarchy[] = $address;
            }
        }

        return $hierarchy;
    }

    /**
     * 获取毫秒
     * @return float
     * Date:    2024/8/15 13:33
     */
    public function getMsectime(): float
    {
        list($msec, $sec) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    }

}
